package com.checkoutcheckins.client.data;

import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import com.checkoutcheckins.client.data.foursquare.Checkin;
import com.checkoutcheckins.client.data.foursquare.FoursquareCheckins;
import com.google.gwt.user.client.ui.FlexTable;
import com.google.gwt.user.client.ui.HTML;
import com.google.gwt.user.client.ui.HasHorizontalAlignment;
import com.google.gwt.user.client.ui.HasVerticalAlignment;
import com.google.gwt.user.client.ui.Widget;

public class Utils {

	public static String getMostFrequentVenue(FoursquareCheckins fsCheckins) {
		HashMap<String, Integer> venueMap = new HashMap<String, Integer>();

		System.out.println("Checkin size: " + fsCheckins.getCheckins().size());

		for (Checkin checkin : fsCheckins.getVenueCheckins()) {
			if (venueMap.containsKey(checkin.getVenue().getName())) {
				venueMap.put(checkin.getVenue().getName(), venueMap.get(checkin
						.getVenue().getName()) + 1);
			} else {
				venueMap.put(checkin.getVenue().getName(), 1);
			}
		}

		venueMap = (HashMap<String, Integer>) sortByValue(venueMap);

		return venueMap.keySet().iterator().next();

	}

	@SuppressWarnings("unchecked")
	public static String getMostFrequenctCity(FoursquareCheckins fsCheckins) {

		System.out.println("Checkin size: " + fsCheckins.getVenueCheckins());

		HashMap<String, Integer> cityMap = new HashMap<String, Integer>();

		for (Checkin checkin : fsCheckins.getVenueCheckins()) {
			if (cityMap.containsKey(checkin.getVenue().getCity())) {
				cityMap.put(checkin.getVenue().getCity(), cityMap.get(checkin
						.getVenue().getCity()) + 1);
			} else {
				if (checkin.getVenue().getCity() != null
						&& !checkin.getVenue().getCity().equals("")) {
					cityMap.put(checkin.getVenue().getCity(), 1);
				}
			}
		}

		cityMap = (HashMap<String, Integer>) sortByValue(cityMap);

		return cityMap.keySet().iterator().next();
	}

	@SuppressWarnings("unchecked")
	static Map sortByValue(Map map) {
		List list = new LinkedList(map.entrySet());
		Collections.sort(list, new Comparator() {
			public int compare(Object o1, Object o2) {
				return ((Comparable) ((Map.Entry) (o2)).getValue())
						.compareTo(((Map.Entry) (o1)).getValue());
			}
		});
		// logger.info(list);
		Map result = new LinkedHashMap();
		for (Iterator it = list.iterator(); it.hasNext();) {
			Map.Entry entry = (Map.Entry) it.next();
			result.put(entry.getKey(), entry.getValue());
		}
		return result;
	}

	public static void addRowToTable(FlexTable table, String html) {
		int rows = table.getRowCount();
		table.setHTML(rows, 0, html);
		table.getFlexCellFormatter().setHorizontalAlignment(rows, 0,
				HasHorizontalAlignment.ALIGN_CENTER);
	}

	public static void addRowToTable(FlexTable table, Widget widget) {
		int rows = table.getRowCount();
		table.setWidget(rows, 0, widget);
	}

	public static String humanFriendlyDate(Date checkinDate) {

		System.out.println(checkinDate.getTime());

		Date created = checkinDate;
		Date today = new Date();

		// how much time since (ms)
		Long duration = today.getTime() - created.getTime();

		int second = 1000;
		int minute = second * 60;
		int hour = minute * 60;
		int day = hour * 24;

		if (duration < second * 7) {
			return "right now";
		}

		if (duration < minute) {
			int n = (int) Math.floor(duration / second);
			return n + " seconds ago";
		}

		if (duration < minute * 2) {
			return "about 1 minute ago";
		}

		if (duration < hour) {
			int n = (int) Math.floor(duration / minute);
			return n + " minutes ago";
		}

		if (duration < hour * 2) {
			return "about 1 hour ago";
		}

		if (duration < day) {
			int n = (int) Math.floor(duration / hour);
			return n + " hours ago";
		}
		if (duration > day && duration < day * 2) {
			return "yesterday";
		}

		if (duration < day * 365) {
			int n = (int) Math.floor(duration / day);
			return n + " days ago";
		} else {
			return "over a year ago";
		}
	}
}
